package app.wxchat;

import app.models.wx.Menu;
import app.models.wx.MessageSetting;
import app.models.member.Member;
import com.github.sog.config.JFinalApp;
import com.github.sog.kit.encry.EncodeKit;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.io.Files;
import com.jfinal.kit.PathKit;
import com.jfinal.module.wxchat.core.Constants;
import com.jfinal.module.wxchat.message.OutputMessage;
import com.jfinal.module.wxchat.message.output.Item;
import com.jfinal.module.wxchat.message.output.NewsOutputMessage;
import com.jfinal.module.wxchat.message.output.TextOutputMessage;
import com.jfinal.module.wxchat.utils.MessageUtil;
import com.jfinal.upload.UploadFile;
import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.name.Rename;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.*;

/**
 * <p>
 * <p/>
 * </p>
 *
 * @author Jerry Ou
 * @version 1.0 2014-04-17 00:04
 * @since JDK 1.6
 */
public class WxChatMessageHelper {

    public OutputMessage parseMenuMessage(Menu menu, Member member) {
        String content = menu.getStr("json");
        try {
            Map<String, String> map = MessageUtil.parseXml(content);
            String messageType = map.get("MsgType");
            Class<? extends OutputMessage> clz = null;
            if (Constants.MSGTYPE_NEWS.equals(messageType)) {
                clz = NewsOutputMessage.class;
            } else {
                clz = TextOutputMessage.class;
            }
            content = content.replaceAll("_mid_", member.get("id").toString()).replaceAll("_wxno_", member.getStr("wx_no"));
            return MessageUtil.xmlToOutputMessage(content, clz);
        } catch (Exception e) {
            return new TextOutputMessage.Builder("", "", System.currentTimeMillis(), Constants.MSGTYPE_TEXT).content("访问出错了，请联系管理人员").build();
        }
    }

    public OutputMessage parseMessageWithParamVals(MessageSetting messageSetting, Member member, Map<String, Object> map) {
        if (messageSetting != null) {
            boolean messageType = messageSetting.getBoolean("message_type");
            Class<? extends OutputMessage> clz = null;
            if (!messageType) {
                clz = NewsOutputMessage.class;
            } else {
                clz = TextOutputMessage.class;
            }
            String content = messageSetting.getStr("content");
            //将所有的链接中的约定参数转换成实际值
            if (map != null) {
                Set<Map.Entry<String, Object>> entitySet = map.entrySet();
                for (Map.Entry<String, Object> entry : entitySet) {
                    String key = entry.getKey();
                    Object val = entry.getValue();
                    content = content.replaceAll(key, val.toString());
                }
            }
            return MessageUtil.xmlToOutputMessage(content, clz);
        }
        return null;
    }

    public OutputMessage parseMessage(MessageSetting messageSetting, Member member) {
        if (messageSetting != null) {
            boolean messageType = messageSetting.getBoolean("message_type");
            Class<? extends OutputMessage> clz = null;
            if (!messageType) {
                clz = NewsOutputMessage.class;
            } else {
                clz = TextOutputMessage.class;
            }
            String content = messageSetting.getStr("content");
            //将所有的链接中的约定参数转换成实际值
            content = content.replaceAll("_mid_", member.get("id").toString()).replaceAll("_wxno_", member.getStr("wx_no"));
            return MessageUtil.xmlToOutputMessage(content, clz);
        }
        return null;
    }

    public OutputMessage convert(String messageType, List<UploadFile> files, Enumeration<String> paraNames, HttpServletRequest request) {
        if (Constants.MSGTYPE_TEXT.equals(messageType)) {
            TextOutputMessage.Builder builder = new TextOutputMessage.Builder("${toUserName}", "${fromUserName}", 0l, Constants.MSGTYPE_TEXT);
            builder.content(request.getParameter("textcontent"));
            return builder.build();
        } else if (Constants.MSGTYPE_NEWS.equals(messageType)) {
            NewsOutputMessage.Builder builder = new NewsOutputMessage.Builder("${toUserName}", "${fromUserName}", 0l, Constants.MSGTYPE_NEWS);
            TreeMap<String, Item> map = Maps.newTreeMap();
            while (paraNames.hasMoreElements()) {
                String paraName = paraNames.nextElement();
                putVal(paraName, map, request);
            }

            if (files != null && !files.isEmpty()) {
                String domain = JFinalApp.domain;
                for (UploadFile file : files) {
                    String paraName = file.getParameterName();
                    String suffix = getSuffix("_file", paraName);
                    Item item = map.get(suffix);
                    if (item == null) {
                        continue;
                    }
                    String picUrl = saveUploadFile(file, request);
                    item.setPicUrl(domain + picUrl);
                }
            }

            List<Item> items = Lists.newArrayList();
            if (!map.isEmpty()) {
                Set<Map.Entry<String, Item>> entrySet = map.entrySet();
                for (Map.Entry<String, Item> entry : entrySet) {
                    items.add(entry.getValue());
                }
            }
            builder.articleCount(items.size());
            builder.articles(items);
            return builder.build();
        }
        return null;
    }

    private static final String uploadroot = "/attachment/";

    private String saveUploadFile(UploadFile upfile, HttpServletRequest request) {
        String realPath = PathKit.getWebRootPath();

        File file = upfile.getFile();
        String filedataFileName = upfile.getOriginalFileName();
        String extension = Files.getFileExtension(filedataFileName);

        String savefilename = uploadroot + EncodeKit.toUUID() + "." + extension;
        if (file != null) {
            File saveNewFile = new File(realPath, savefilename);
            try {
                Files.createParentDirs(saveNewFile);
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (file.renameTo(saveNewFile)) {
                try {
                    Thumbnails.of(saveNewFile).size(200, 120).outputFormat(extension).toFiles(Rename.SUFFIX_DOT_THUMBNAIL);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return savefilename;
        }
        return null;
    }

    private void putVal(String paraName, Map<String, Item> map, HttpServletRequest request) {
        if (paraName.startsWith("title")) {
            String suffix = getSuffix("title", paraName);
            Item item = map.get(suffix);
            if (item == null) {
                item = new Item("", "", "", "");
            }
            map.put(suffix, item);
            item.setTitle(request.getParameter(paraName));
        } else if (paraName.startsWith("content")) {
            String suffix = getSuffix("content", paraName);
            Item item = map.get(suffix);
            if (item == null) {
                item = new Item("", "", "", "");
            }
            map.put(suffix, item);
            item.setDescription(request.getParameter(paraName));
        } else if (paraName.startsWith("url")) {
            String suffix = getSuffix("url", paraName);
            Item item = map.get(suffix);
            if (item == null) {
                item = new Item("", "", "", "");
            }
            map.put(suffix, item);
            item.setUrl(request.getParameter(paraName));
        }
    }

    private String getSuffix(String prefix, String str) {
        return str.substring(prefix.length());
    }

}
